/**
 * AbstractCreditInfoCollectionComponent.java
 * author: yujiakui
 * 2017年8月30日
 * 上午10:39:21
 */
package com.ctim.service.component.impl;

import java.text.MessageFormat;

import org.springframework.beans.factory.annotation.Autowired;

import com.ctim.common.exception.PcsRunTimeException;
import com.ctim.model.IsvRequestParamInfo;
import com.ctim.model.ThirdPartyInvokeCfg;
import com.ctim.service.component.CreditInfoCollectionComponent;
import com.ctim.service.component.assemble.IsvRequestParamAssemble;
import com.ctim.service.component.assemble.IsvRequestParamAssembleFactory;
import com.ctim.service.enums.IsvRequestParamAssembleTypeEnum;
import com.ctim.service.enums.ThirdPartyReturnTypeEnum;
import com.ctim.service.integration.ThirdPartyResponseHandleTemplate;
import com.ctim.service.integration.pengyuan.ThirdPartyInvokeClient;

/**
 * @author yujiakui
 *
 *         上午10:39:21
 *
 *         抽象征信信息采集组件
 *
 */
public abstract class AbstractCreditInfoCollectionComponent
		implements CreditInfoCollectionComponent {

	@Autowired
	private ThirdPartyInvokeClient thirdPartyInvokeClient;

	/*
	 *
	 * @see
	 * com.ctim.service.component.CreditInfoCollectionComponent#collect(com.ctim
	 * .model.ThirdPartyInvokeCfg, com.ctim.model.IsvRequestParamInfo)
	 */
	@Override
	public Object collect(ThirdPartyInvokeCfg invokeCfg, IsvRequestParamInfo isvRequestParamInfo) {
		// 1. 组装条件参数
		String reqCndParam = assembleReqCndParam(invokeCfg, isvRequestParamInfo);

		// 2. 调用外部接口返回结果
		Object invokeResult = invokeClient(invokeCfg, isvRequestParamInfo, reqCndParam);

		// 3. 获得对应的校验解析模板类
		ThirdPartyResponseHandleTemplate template = assembleHandleTemplate(invokeCfg,
				isvRequestParamInfo);

		// 4. 使用模板进行处理
		// 5. TODO 对领域模型进行保存
		return template.doHandle(invokeResult, isvRequestParamInfo.getParserResultDomainClass());
	}

	/**
	 * 组装对应的校验解析模板类
	 *
	 * @param invokeCfg
	 * @param isvRequestParamInfo
	 * @return
	 */
	protected abstract ThirdPartyResponseHandleTemplate assembleHandleTemplate(
			ThirdPartyInvokeCfg invokeCfg, IsvRequestParamInfo isvRequestParamInfo);

	/**
	 * 调用第三方接口进行操作
	 *
	 * @param invokeCfg
	 * @param isvRequestParamInfo
	 * @param reqCondition
	 * @return
	 */
	protected Object invokeClient(ThirdPartyInvokeCfg invokeCfg,
			IsvRequestParamInfo isvRequestParamInfo, String reqCondition) {
		// 调用外部接口
		ThirdPartyReturnTypeEnum thirdPartyReturnTypeEnum = ThirdPartyReturnTypeEnum
				.getByCode(isvRequestParamInfo.getInterfaceReturnType());
		return thirdPartyInvokeClient.invoke(invokeCfg, isvRequestParamInfo.getInterfaceName(),
				reqCondition, thirdPartyReturnTypeEnum);

	}

	/**
	 * 组装请求参数
	 *
	 * @param invokeCfg
	 * @param isvRequestParamInfo
	 * @return
	 */
	protected String assembleReqCndParam(ThirdPartyInvokeCfg invokeCfg,
			IsvRequestParamInfo isvRequestParamInfo) {
		// 1. 根据请求参数需要的类型获得对应的组装器
		IsvRequestParamAssemble assemble = IsvRequestParamAssembleFactory.getAssembleByType(
				IsvRequestParamAssembleTypeEnum.getByCode(isvRequestParamInfo.getReqParamFormat()));

		if (null == assemble) {
			throw new PcsRunTimeException(MessageFormat.format(
					"根据code={0}查询对应的组装器不存在,invokeCfg={1},isvRequestInfo={2}",
					isvRequestParamInfo.getReqParamFormat(), invokeCfg, isvRequestParamInfo));
		}

		// 请求条件进行组装
		return assemble.assemble(isvRequestParamInfo);
	}

}
